<template>
    <v-dialog v-model="svgDialog" persistent scrollable max-width="85%" :fullscreen="$vuetify.breakpoint.xsOnly">
      <v-card>
        <v-card-title>
          <span class="headline">{{ name }}</span>
        </v-card-title>
        <v-divider></v-divider>
        <v-card-text class="px-0 py-0">
          <v-tabs v-model="active" color="cyan" dark slider-color="yellow">
            <v-tab ripple>
                ProjectSvg
            </v-tab>
            <v-tab ripple>
                ProjectTable
            </v-tab>
             <v-tab-item>
              <v-container grid-list-md>
                <v-layout wrap>
                  <svg :width="width" :height="height" ref="prjSvg"></svg>
                </v-layout>
              </v-container>
            </v-tab-item>
            <v-tab-item>
              <v-container grid-list-md>
                <v-layout wrap>
                  <v-flex xs12 sm6 md3>
                    <v-card-title>
                      <span class="headline">项目主机对应表</span>
                    </v-card-title>
                    <tr class="svgTable"><th>主机名</th><th>IP地址</th><th>状态</th></tr>
                    <tr class="svgTable" v-for="(value) in this.$store.state.listproject.svgTable.projectHosts" :key="value.id">
                      <td>{{value.hostname}}</td>
                      <td>{{value.ip}}</td>
                      <td>{{value.status}}</td>
                    </tr>
                  </v-flex>
                  <v-flex xs12 sm6 md3>
                    <v-card-title>
                      <span class="headline">服务主机对应表</span>
                    </v-card-title>
                    <tr class="svgTable"><th>主机名</th><th>IP地址</th></tr>
                    <tr class="svgTable" v-for="(value) in this.$store.state.listproject.svgTable.serviceHosts" :key="value.id">
                      <td>{{value.hostname}}</td>
                      <td>{{value.ip}}</td>
                    </tr>
                  </v-flex>
                  <v-flex xs12 sm6 md6>
                    <v-card-title>
                      <span class="headline">服务表</span>
                    </v-card-title>
                    <tr class="svgTable"><th>服务名</th><th>内网IP</th><th>内网域名</th><th>外网IP</th><th>外网域名</th></tr>
                    <tr class="svgTable" v-for="(value) in this.$store.state.listproject.svgTable.services" :key="value.id">
                      <td>{{value.name}}</td>
                      <td>{{value.innerIp}}</td>
                      <td width="30">{{value.innerUrl}}</td>
                      <td>{{value.OutterIpSource__ipAddress}}</td>
                      <td>{{value.url}}</td>
                    </tr>
                  </v-flex>
                </v-layout>
              </v-container>
            </v-tab-item>
          </v-tabs>
        </v-card-text>
        <v-divider></v-divider>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="primary" small @click.native="closeProjectSvg()"><h4>关闭</h4></v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
</template>

<script>
import * as d3 from 'd3'
import {ellipseForce} from '../../vendor/ellipseForce'
import { createNamespacedHelpers } from 'vuex'
const { mapActions } = createNamespacedHelpers('projectSvg')

export default {
  name: 'projectSvg',
  data: function () {
    return this.$store.state.projectSvg
  },
  methods: {
    ...mapActions({
      loadSvg: 'loadSvg',
      closeProjectSvg: 'closeProjectSvg'
    }),
    ticked () {
      this.link
        .attr('x1', function (d) { return d.source.x })
        .attr('y1', function (d) { return d.source.y })
        .attr('x2', function (d) { return d.target.x })
        .attr('y2', function (d) { return d.target.y })
      this.node
        .attr('cx', function (d) { return d.x })
        .attr('cy', function (d) { return d.y })
      this.text
        .attr('x', function (d) { return d.x })
        .attr('y', function (d) { return d.y })
    },
    dragstarted (d) {
      if (!d3.event.active) this.simulation.alphaTarget(0.3).restart()
      d.fx = d.x
      d.fy = d.y
    },
    dragged (d) {
      d.fx = d3.event.x
      d.fy = d3.event.y
    },
    dragended (d) {
      if (!d3.event.active) this.simulation.alphaTarget(0)
      d.fx = null
      d.fy = null
    }
  },
  props: {
    svgDialog: {
      type: Boolean,
      default: null
    },
    id: {
      type: Number,
      default: null
    }
  },
  watch: {
    svgDialog () {
      if (this.svgDialog) {
        let graphs = this.$store.state.listproject.graph
        let svg = d3.select('svg')
        let width = +svg.attr('width')
        let height = +svg.attr('height')
        let color = d3.scaleOrdinal(d3.schemeCategory20)
        let nd
        for (var i = 0; i < graphs.nodes.length; i++) {
          nd = graphs.nodes[i]
          nd.rx = nd.name.length * 5.5
          nd.ry = 12
        }
        this.simulation = d3.forceSimulation()
          .force('link', d3.forceLink().id(function (d) { return d.id }))
          .force('collide', ellipseForce(6, 0.5, 5))
          .force('center', d3.forceCenter(width / 2, height / 2))
        this.link = svg.append('g')
          .attr('class', 'link')
          .selectAll('line')
          .data(graphs.links)
          .enter().append('line')
          .attr('stroke-width', function (d) { return Math.sqrt(d.value) })
        this.node = svg.append('g')
          .attr('class', 'node')
          .selectAll('ellipse')
          .data(graphs.nodes)
          .enter().append('ellipse')
          .attr('rx', function (d) { return d.rx })
          .attr('ry', function (d) { return d.ry })
          .attr('fill', function (d) { return color(d.group) })
          .call(d3.drag()
            .on('start', this.dragstarted)
            .on('drag', this.dragged)
            .on('end', this.dragended))
        this.text = svg.append('g')
          .attr('class', 'labels')
          .selectAll('text')
          .data(graphs.nodes)
          .enter().append('text')
          .attr('dy', 2)
          .attr('text-anchor', 'middle')
          .text(function (d) { return d.name })
          .attr('fill', 'white')
        this.simulation
          .nodes(graphs.nodes)
          .on('tick', this.ticked)
        this.simulation.force('link')
          .links(graphs.links)
      } else {
        d3.select('svg')
        this.$refs.prjSvg.innerHTML = ''
      }
    }
  },
  mounted () {

  }
}
</script>
<style>
  .link line {
  stroke: #999;
  stroke-opacity: 0.6;
}
.labels text {
  pointer-events: none;
  font: 10px sans-serif;
}
</style>
